/**
 * @description paperModel Service
 */

 const {
  paperModel,
  questionModel
} = require('../db/index')
const Op = require('sequelize').Op

async function addData(params) {
  const result = await paperModel.create(params)
  const data = result.dataValues
  return data
}

async function updateData(
  params,
  id
) {
  // 拼接修改内容
  const updateObj = params

  // 拼接查询条件
  const whereOption = {}
  if (id) {
    whereOption.id = id
  }

  // 执行修改
  const result = await paperModel.update(updateObj, {
    where: whereOption
  })
  return result[0] > 0
}

async function deleteData(id) {
  const result = await paperModel.destroy({
    where: {
      id
    }
  })
  return result > 0
}

async function queryByNo(no) {
  const result = await paperModel.findAll({
    where: {
      no
    }
  })
  return {
    exsit: !!result.length
  }
}

async function queryAll(params) {
  const {
    page = 1,
    pageSize = 10, 
    key
  } = params
  const whereOption = {}
  if (key) {
    whereOption[Op.or] = [
      { name: { [Op.like]: `%${key}%` } },  
    ];
  }
  const result = await paperModel.findAll({
    limit: pageSize,
    offset: (page - 1) * pageSize,
    where: whereOption,
  })
  const total = await paperModel.findAll({
    where: whereOption
  })
  return {
    total: total.length || 0,
    data: result || []
  }
}

function getRandomUniqueObjects(objectsArray, n) {
  // 创建一个数组副本，以免修改原始数组  
  let copyArray = [...objectsArray];  
  let result = [];  

  // 随机选择n个不重复的对象  
  for (let i = 0; i < n; i++) {  
      let randomIndex = Math.floor(Math.random() * copyArray.length);  
      result.push(copyArray[randomIndex]);  
      // 从副本中移除已选中的对象，以确保不重复  
      copyArray.splice(randomIndex, 1);  
  }  

  return result;  
} 

/**
 * 
 * @param {*} command： 1：简单 、2：中等、3：困难
 * @returns 
 */
function handleData(num, command, qs) {
  try {
    const {qs1, qs2, qs3} = qs
    let questionIds = []
    switch(command) {
      case '1':
        let num1 = Math.round(num * 0.4)
        if (num == 1) {
          num1 = num
        }
        // 如果数量不足 就使用更高难度的
        if (qs1.length < num1) {
          num1 = qs1.length
        }
        if (num1 && qs1.length) {
          let qs = getRandomUniqueObjects(qs1, num1)
          if (qs) {
            questionIds = questionIds.concat(qs)
          }
        }
        let numLeft = num - num1
        if (numLeft) {
          let num2 = Math.round(numLeft * 0.5)
          if (qs2.length < num2) {
            num2 = qs2.length
          }
          
          if (num2 && qs2.length) {
            let qs = getRandomUniqueObjects(qs2, num2)
            if (qs) {
              questionIds = questionIds.concat(qs)
            }
          }

          let num3 = num - num1 - num2
          if (num3 && qs3.length) {
            let qs = getRandomUniqueObjects(qs3, num3)
            if (qs) {
              questionIds = questionIds.concat(qs)
            }
          }
        }
        break;
      case '2':
        let num1c = Math.round(num * 0.3)
        // 如果数量不足 就使用更高难度的
        if (qs1.length < num1c) {
          num1c = qs1.length
        }
        if (qs1.length && num1c) {
          let qsm = getRandomUniqueObjects(qs1, num1c)
          if (qsm) {
            questionIds = questionIds.concat(qsm)
          }
        }
        
        let numLeftm = num - num1c
        if (numLeftm) {
          let num2 = Math.round(numLeftm * 0.57)
          if (qs2.length < num2) {
            num2 = qs2.length
          }
          
          if (qs2.length && num2) {
            let qsm = getRandomUniqueObjects(qs2, num2)
            if (qsm) {
              questionIds = questionIds.concat(qsm)
            }
          }

          let num3 = num - num1c - num2
          if (num3 && qs3.length) {
            let qsm = getRandomUniqueObjects(qs3, num3)
            if (qsm) {
              questionIds = questionIds.concat(qsm)
            }
          }
        }
        break;
      case '3':
        let num1h = Math.round(num * 0.4)
        // 如果数量不足 就使用更高难度的
        if (qs1.length < num1h) {
          num1h = qs1.length
        }
        if (num1h && qs1.length) {
          let qsh = getRandomUniqueObjects(qs1, num1h)
          if (qsh) {
            questionIds = questionIds.concat(qsh)
          }
        }
        
        let numLefth = num - num1h
        if (numLefth) {
          let num2 = Math.round(numLefth * 0.43)
          if (qs2.length < num2) {
            num2 = qs2.length
          }
          if (num2 && qs2.length) {
            let qsh = getRandomUniqueObjects(qs2, num2)
            if (qsh) {
              questionIds = questionIds.concat(qsh)
            }
          }

          let num3 = num - num1h - num2
          if (num3) {
            if (qs3.length && num3) {
              let qsh = getRandomUniqueObjects(qs3, num3)
              if (qsh) {
                questionIds = questionIds.concat(qsh)
              }
            }
          }
        }
        break
    }
    return questionIds
  } catch (error) {
    console.log(error)
  }
}
async function addAuto(params) {
  let questions = []
  const { name, blank, single, multi, bool, big, command } = params
  if (blank > 0) {
    let blankData = await questionModel.findAll({
      where: {
        type: '填空'
      }
    })
    if (blank > blankData.length) {
      return {
        code: 500,
        msg: '填空题数量有限，请调整个数。'
      }
    } else {
      let qs1 = blankData.filter(v => v.hard == '1')
      let qs2 = blankData.filter(v => v.hard == '2')
      let qs3 = blankData.filter(v => v.hard == '3')
      let qsRes = handleData(blank, command, {
        qs1,
        qs2,
        qs3
      })
      if (qsRes.length < blank) {
        return {
          code: 500,
          msg: '填空题难度系数分配数量有限，请调整个数或增加题库。'
        }
      }
      questions = questions.concat(qsRes)
    }
  }

  if (single > 0) {
    let singleData = await questionModel.findAll({
      where: {
        type: '单选'
      }
    })
    if (single > singleData.length) {
      return {
        code: 500,
        msg: '单选题数量有限，请调整个数。'
      }
    } else {
      let qs1 = singleData.filter(v => v.hard == '1')
      let qs2 = singleData.filter(v => v.hard == '2')
      let qs3 = singleData.filter(v => v.hard == '3')
      let qsRes = handleData(single, command, {
        qs1,
        qs2,
        qs3
      })
      if (qsRes.length < single) {
        return {
          code: 500,
          msg: '单选题难度系数分配数量有限，请调整个数或增加题库。'
        }
      }
      questions = questions.concat(qsRes)
    }
  }

  if (multi > 0) {
    let data = await questionModel.findAll({
      where: {
        type: '多选'
      }
    })
    if (multi > data.length) {
      return {
        code: 500,
        msg: '多选题数量有限，请调整个数。'
      }
    } else {
      let qs1 = data.filter(v => v.hard == '1')
      let qs2 = data.filter(v => v.hard == '2')
      let qs3 = data.filter(v => v.hard == '3')
      let qsRes = handleData(multi, command, {
        qs1,
        qs2,
        qs3
      })
      if (qsRes.length < multi) {
        return {
          code: 500,
          msg: '多选题难度系数分配数量有限，请调整个数或增加题库。'
        }
      }
      questions = questions.concat(qsRes)
    }
  }
  
  if (bool > 0) {
    let data = await questionModel.findAll({
      where: {
        type: '判断'
      }
    })
    if (bool > data.length) {
      return {
        code: 500,
        msg: '判断题数量有限，请调整个数。'
      }
    } else {
      let qs1 = data.filter(v => v.hard == '1')
      let qs2 = data.filter(v => v.hard == '2')
      let qs3 = data.filter(v => v.hard == '3')
      let qsRes = handleData(bool, command, {
        qs1,
        qs2,
        qs3
      })
      if (qsRes.length < bool) {
        return {
          code: 500,
          msg: '判断题难度系数分配数量有限，请调整个数或增加题库。'
        }
      }
      questions = questions.concat(qsRes)
    }
  }
  
  if (big > 0) {
    let data = await questionModel.findAll({
      where: {
        type: '主观题'
      }
    })
    if (big > data.length) {
      return {
        code: 500,
        msg: '主观题数量有限，请调整个数。'
      }
    } else {
      let qs1 = data.filter(v => v.hard == '1')
      let qs2 = data.filter(v => v.hard == '2')
      let qs3 = data.filter(v => v.hard == '3')
      let qsRes = handleData(big, command, {
        qs1,
        qs2,
        qs3
      })
      if (qsRes.length < big) {
        return {
          code: 500,
          msg: '主观题难度系数分配数量有限，请调整个数或增加题库。'
        }
      }
      questions = questions.concat(qsRes)
    }
  }
  const result = await paperModel.create({
    name,
    questions: questions.map(v => v.id).join(',')
  })
  const data = result.dataValues
  return {
    code: 200
  }
}

module.exports = {
  addData,
  updateData,
  deleteData,
  queryAll,
  queryByNo,
  addAuto
}